<?php

namespace App\Models\Fee;

use App\Enums\OpenShop\InvestmentPromotion\ErrCode;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Models\BaseModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderPayHistoryModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserBaseInfoModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserIdentityCardModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Models\Traits\KfSoftDeletes;
use App\Models\Traits\KfUid;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;

class FeeAnnualOrderModel extends BaseModel
{
    use KfUid;

    use KfSoftDeletes;

    protected $table = 'fee_annual_order';

    protected $fillable = [
        'feeOrderNo',
        'shopId',
        'shouldPayPrice',
        'payPrice',
        'payStatus',
        'manageFee',
        'systemFee',
        'endTime',
        'payTime',
        'isDeleted',
        'startYear',
    ];

    protected $appends = [
        'payStatusText',
        'statusText',
    ];

    const PAY_STATUS_OK   = 2; // 已支付
    const PAY_STATUS_PART = 1; // 部分支付
    const PAY_STATUS_WAIT = 0; // 待支付

    const STATUS_MAP = [
        self::PAY_STATUS_WAIT => "待支付",
        self::PAY_STATUS_PART => "部分支付",
        self::PAY_STATUS_OK   => "已支付"
    ];

    const STATUS_ORDER_ON  = 1;   //正常订单
    const STATUS_ORDER_OFF = 0;   //过期订单

    public function onePaySuccess(int $payPrice): self
    {
        // 已支付金额累加
        $this->payPrice += $payPrice;

        if ($this->payPrice >= $this->shouldPayPrice) {

            // 整单支付完成
            $this->payStatus = self::PAY_STATUS_OK;
            $this->payTime   = time();
        } elseif ($this->payFee < $this->shouldPayPrice) {

            // 部分支付完成
            $this->payStatus = self::PAY_STATUS_PART;
        } else {

            // 支付金额超过应付
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_PAY_PRICE_OVERFLOW)
            );
        }

        $this->save();

        return $this;
    }

    /**
     * @return HasOneThrough
     */
    public function signOrderRel(): HasOneThrough
    {
        return $this->hasOneThrough(
            OpenShopSignOrderModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'mainProcessId',
            'shopId',
            'id',
        );
    }

    /**
     * @return HasOneThrough
     */
    public function siteLocationRel(): HasOneThrough
    {
        return $this->hasOneThrough(
            OpenShopSiteLocationModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'mainProcessId',
            'shopId',
            'id',
        )->whereIn('source',
            [OpenShopSiteLocationModel::SOURCE_OPEN_SHOP, OpenShopSiteLocationModel::SOURCE_HOUSING]);
    }

    /**
     * @return HasOneThrough
     */
    public function userBaseInfoRel(): HasOneThrough
    {
        return $this->hasOneThrough(
            OpenShopUserBaseInfoModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'orderNo',
            'shopId',
            'orderNo',
        );
    }

    /**
     * @return HasOneThrough
     */
    public function identityCardRel(): HasOneThrough
    {
        return $this->hasOneThrough(
            OpenShopUserIdentityCardModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'orderNo',
            'shopId',
            'orderNo',
        );
    }

    public function getPayStatusTextAttribute(): string
    {
        return self::STATUS_MAP[$this->payStatus] ?? '-';
    }

    public function getStatusTextAttribute(): string
    {
        if ($this->payStatus != self::PAY_STATUS_OK) {
            return self::STATUS_MAP[$this->payStatus] ?? '待支付';
        } else {
            return '已支付';
        }
    }

    /**
     * @return HasOneThrough
     */
    public function startBusinessRel(): HasOneThrough
    {
        return $this->hasOneThrough(
            OpenShopStartBusinessModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'mainProcessId',
            'shopId',
            'id',
        );
    }

    public function mainProcessRel(): HasOne
    {
        return $this->hasOne(OpenShopMainProcessModel::class, 'shopId', 'shopId');
    }

    public function mainProcessesRel(): HasMany
    {
        return $this->hasMany(OpenShopMainProcessModel::class, 'shopId', 'shopId');
    }

    public function payHistoryRel(): HasMany
    {
        return $this->hasMany(OpenShopSignOrderPayHistoryModel::class, "bizId", "feeOrderNo");
    }

    public function changesLogRel(): HasMany
    {
        return $this->hasMany(FeeAnnualChangesModel::class, 'feeOrderNo', 'feeOrderNo');
    }


    /**
     * 获取未支付完成订单列表
     *
     * @param int $shopId
     * @return Builder[]|Collection
     */
    public static function unpaidCompletionList(int $shopId)
    {
        return self::query()
                   ->where('shopId', $shopId)
                   ->whereIn(
                       'payStatus',
                       [FeeAnnualOrderModel::PAY_STATUS_WAIT, FeeAnnualOrderModel::PAY_STATUS_PART]
                   )->get();
    }
}
